package club.vann.kafka.mock.util;

import club.vann.kafka.mock.common.exception.BussinessRuntimeException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/** Stirng处理工具累。 */
public class StringUtil {
  /** 元素分隔符 */
  public static final String DELIMITER = ",";

  /** 分号分隔符 */
  public static final String DELIMITER_SEMI = ";";

  /** 冒号分隔符 */
  public static final String DELIMITER_COLON = ":";

  /** 币对分隔符 */
  public static final String PAIR_DELIMITER = "/";

  /** 斜线分割符 */
  public static final String SLASH = "/";

  /** 中横线分隔符 */
  public static final String MID_DELIMITER = "-";

  /** 下划线分隔符 */
  public static final String UNDER_LINE_DELIMITER = "_";

  /** 换行符 */
  public static final String LINE_N = "\n";

  /** 竖线换行符 */
  public static final String LINE_HORIZON = "|";

  /** 竖线 */
  public static final String VERTICAL = "\\|";

  /** 空字符串 */
  public static final String EMPTY_STRING = "";

  /** 左括号 [ */
  public static final String BRACKET_LEFT = "[";

  /** 右括号 ] */
  public static final String BRACKET_RIGHT = "]";

  /** 转义分号 */
  public static final String REG_SEMI = "\"";

  /** DOT */
  public static final String DOT = ".";

  /** NUMBER_SIGN */
  public static final String NUMBER_SIGN = "#";

  private StringUtil() {}

  private static final char[] HEX_CHARS = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
  };

  /**
   * String数组使用 split 合并成字符串。
   *
   * @param array String字符串
   * @param split 区分标志
   * @return
   */
  public static String array2String(String[] array, String split) {
    return String.join(split, array);
  }

  /**
   * String字符串按照 split 拆分成数组。
   *
   * @param string string字符串
   * @param split 区分标志
   * @return
   */
  public static String[] string2Array(String string, String split) {
    // 去除空格
    string = string.replace(" ", "");
    return string.split(split);
  }

  public static List<String> mapKeyToList(Map<String, Object> map) {
    if (ObjectUtils.isEmpty(map)) {
      return Collections.emptyList();
    }
    Set<String> keys = map.keySet();
    return keys.stream().toList();
  }

  /**
   * 字节数组SHA512编码。
   *
   * @param source 字节数组
   * @param salt salt
   * @return SHA512编码后的字符串
   */
  public static String sha512Encoded(byte[] source, String salt) {
    String encoded;
    try {
      MessageDigest md = MessageDigest.getInstance("SHA-512");
      byte[] digested = md.digest(source);
      char[] chars = encodeHex(digested, salt.getBytes());
      encoded = new String(chars);
    } catch (NoSuchAlgorithmException e) {
      throw new BussinessRuntimeException("SHA512算法未找到");
    }

    return encoded;
  }

  /**
   * 字符串分隔符格式化。
   *
   * @param string
   * @param sourceDelimiter
   * @param targetDelimiter
   * @return
   */
  public static String stringFormatByDelimiter(
      String string, String sourceDelimiter, String targetDelimiter) {
    return string.replace(sourceDelimiter, targetDelimiter);
  }

  /**
   * 判断两个字符串是否相等。
   *
   * <p>注意： str1 == null & str2 == null 时，该方法返回 true
   *
   * @param str1 字符串1
   * @param str2 字符串2
   * @return 字符串1等于字符串2
   */
  public static boolean isEqual(String str1, String str2) {
    if (ObjectUtils.isEmpty(str1) && ObjectUtils.isEmpty(str2)) {
      return true;
    }
    if (ObjectUtils.isEmpty(str1) || ObjectUtils.isEmpty(str2)) {
      return false;
    }
    return str1.equals(str2);
  }

  public static boolean isEmpty(String str) {
    return StringUtils.isEmpty(str);
  }

  private static char[] encodeHex(byte[] bytes, byte[] salt) {
    char[] chars = new char[128];
    for (int i = 0; i < chars.length; i = i + 2) {
      byte b = bytes[i / 2];
      b &= salt[i % salt.length];
      chars[i] = HEX_CHARS[(b >>> 0x4) & 0xf];
      chars[i + 1] = HEX_CHARS[b & 0xf];
    }
    return chars;
  }
}
